﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using smartcrm.Utilities;
using System.Web.Script.Serialization;
using Newtonsoft.Json.Linq;
using System.IO;
using smartcrm.Models;
using System.Data.Common;
using System.Data.SqlClient;

namespace smartcrm.Controllers
{
    [Authorization]
    public class SystemController : BaseController
    {
        [PermissionAttribute(PermissionNo = "P0403")]
        public new ActionResult OrderTemplate()
        {
            return View();
        }

        public JsonResult GetOriginalTemplate()
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            Company c = Context.Company.FirstOrDefault(m => m.CompanyNo == CompanyNo);

            if (c == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                JavaScriptSerializer json = new JavaScriptSerializer();
                result.Data = new { code = 0, data = json.Deserialize(c.OrderTemplate, typeof(List<Object>)) };
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0403",IsJson=true)]
        public JsonResult UpdateOrderTemplate(string data)
        {
            JsonResult result = new JsonResult();
            Company company = Context.Company.FirstOrDefault(m => m.CompanyNo == CompanyNo);
            if (company == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else if (IS_DEMO)
            {
                result.Data = new { code = 1, message = MSG_IsDemo };
            }
            else
            {
                company.OrderTemplate = data;

                Context.SaveChanges();
                result.Data = new { code = 0 };
            }

            return result;
        }

        [HttpGet]
        [PermissionAttribute(PermissionNo = "P0401")]
        public ActionResult Company()
        {
            Company company = Context.Company.FirstOrDefault(m => m.CompanyNo == CompanyNo);
            if (company == null)
            {
                return Redirect("/Account/Login");
            }
            else
            {
                return View(company);
            }
        }

        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0401")]
        public ActionResult Company(Company c)
        {
            Company company = Context.Company.FirstOrDefault(m => m.CompanyNo == CompanyNo);
            company.CompanyNameOnReport = c.CompanyNameOnReport;
            company.AddressOnReport = c.AddressOnReport;
            company.PostcodeOnReport = c.PostcodeOnReport;
            company.PhoneFaxOnReport = c.PhoneFaxOnReport;

            HttpPostedFileBase file = Request.Files["logofile"];
            if (!string.IsNullOrEmpty(file.FileName) && file.ContentLength > 0)
            {
                String[] tempArray = file.FileName.Split('.');
                string fileExtensionName = tempArray[tempArray.Length - 1];
                string fileName = Path.Combine(LOGO_PATH, CompanyNo + "." + fileExtensionName);
                company.LogoOnReport = CompanyNo + "." + fileExtensionName;
                file.SaveAs(fileName);
            }

            Context.SaveChanges();

            return View(company);
        }

        [PermissionAttribute(PermissionNo = "P0406")]
        public ActionResult Factory()
        {
            List<Factory> allFactories = Context.Factory.Where(m => m.IsActive && m.CompanyNo == CompanyNo).ToList();

            foreach (Factory f in allFactories)
            {
                if (!string.IsNullOrEmpty(f.Contact))
                {
                    f.Contact = Server.HtmlDecode(f.Contact.Replace(System.Environment.NewLine, "</br>"));
                }
            }

            return View(allFactories);
        }

        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0406", IsJson = true)]
        public JsonResult AddFactory(Factory factory)
        {
            JsonResult result = new JsonResult();
            string errorMessage = string.Empty;

            string newFactoryNo = GetNewIdNumber(IdNumberType.Factory);
            factory.FactoryNo = newFactoryNo;
            factory.CompanyNo = CompanyNo;
            factory.IsActive = true;

            try
            {
                Context.Factory.AddObject(factory);
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }
            catch (Exception ex)
            {                
                PutbackNo(newFactoryNo, IdNumberType.Factory);
                throw ex;
            }

            return result;
        }

        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0406", IsJson = true)]
        public JsonResult UpdateFactory(Factory factory)
        {
            JsonResult result = new JsonResult();
            string errorMessage = string.Empty;

            Factory originalFactory = Context.Factory.FirstOrDefault(m => m.FactoryNo == factory.FactoryNo);
            if (originalFactory == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                originalFactory.FactoryName = factory.FactoryName;
                originalFactory.Description = factory.Description;
                originalFactory.Contact = factory.Contact;

                Context.SaveChanges();
                result.Data = new { code = 0 };

            }

            return result;
        }

        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0406", IsJson = true)]
        public JsonResult DeleteFactory(string FactoryNo)
        {
            JsonResult result = new JsonResult();
            string errorMessage = string.Empty;
            Factory originalFactory = Context.Factory.FirstOrDefault(m => m.FactoryNo == FactoryNo);

            if (originalFactory == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else if (IS_DEMO)
            {
                result.Data = new { code = 1, message = MSG_IsDemo };
            }
            else
            {
                originalFactory.IsActive = false;

                Context.SaveChanges();
                result.Data = new { code = 0 };
            }

            return result;
        }

        public JsonResult GetFactory(string FactoryNo)
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            Factory factory = Context.Factory.FirstOrDefault(m => m.FactoryNo == FactoryNo);

            if (factory == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                result.Data = new Factory() { FactoryName = factory.FactoryName, FactoryNo = factory.FactoryNo, Description = factory.Description, Contact = factory.Contact };
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0402")]
        new public ActionResult User()
        {
            UserListModel model = new UserListModel();
            model.Users = Context.User.Where(m => m.CompanyNo == CompanyNo).Select(m => new UserModel() { UserId = m.UserId, UserName = m.UserName, Email = m.Email, Phone = m.Phone, Mobile = m.Mobile, Memo = m.Memo }).ToList();

            foreach (UserModel u in model.Users)
            {
                u.Department = string.Empty;
                List<UserDepartment> lists = Context.UserDepartment.Where(m => m.UserId == u.UserId).ToList();
                foreach (UserDepartment d in lists)
                {
                    u.Department += string.Format("{0}{1}, ", d.Department.DepartmentName, (d.IsManager ? "(经理)" : ""));
                }
                if (!string.IsNullOrEmpty(u.Department))
                {
                    u.Department = u.Department.Substring(0, u.Department.Length - 2);
                }
            }

            model.RoleGroups = Context.RoleGroup.Select(m => new RoleGroupModel { RoleGroupName = m.RoleGroupName, RoleGroupNo = m.RoleGroupNo }).ToList();

            foreach (RoleGroupModel rgm in model.RoleGroups)
            {
                rgm.Permissions = Context.Permission.Where(n => n.RoleGroupNo == rgm.RoleGroupNo).Select(m => new PermissionModel { PermissionNo = m.PermissionNo, PermissionName = m.PermissionName }).ToList();
            }
            return View(model);
        }

        [PermissionAttribute(PermissionNo = "P0402", IsJson = true)]
        public JsonResult GetUser(string UserId)
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            User user = Context.User.FirstOrDefault(m => m.UserId == UserId && m.CompanyNo == CompanyNo);

            if (user == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                result.Data = new { code = 0, data = new { UserId = user.UserId, UserName = user.UserName, Phone = user.Phone, Email = user.Email, Mobile = user.Mobile, Memo = user.Memo } };
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0402", IsJson = true)]
        public JsonResult GetUserPermission(string UserId)
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            User user = Context.User.FirstOrDefault(m => m.UserId == UserId && m.CompanyNo == CompanyNo);

            if (user == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {                
                if (!string.IsNullOrEmpty(user.Permissions))
                {
                    result.Data = new { code = 0, data = user.Permissions.Split(',').ToList() };
                }
                else
                {
                    result.Data = new { code = 0, data = new List<String>()};
                }
                
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0402", IsJson = true)]
        public JsonResult GetUserDepartment(string UserId)
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            User user = Context.User.FirstOrDefault(m => m.UserId == UserId && m.CompanyNo == CompanyNo);

            if (user == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                List<UserDepartment> userDepartments = Context.UserDepartment.Where(m => m.UserId == UserId).ToList();
                List<ListOption> allDepartments = Context.Department.Where(m => m.CompanyNo == CompanyNo).Select(m => new ListOption { OptionValue = m.DepartmentNo, OptionText = m.DepartmentName, AdditionalValue = "" }).ToList();
                foreach (ListOption d in allDepartments)
                {
                    if (userDepartments.FirstOrDefault(m => m.DepartmentNo == d.OptionValue) == null)
                    {
                        d.AdditionalValue = "0";
                    }
                    else
                    {
                        d.AdditionalValue = "1";
                    }
                }
                result.Data = new { code = 0, data = allDepartments };
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0402", IsJson = true)]
        public JsonResult AddUser(User user)
        {
            JsonResult result = new JsonResult();

            User u = Context.User.FirstOrDefault(m => m.UserId == user.UserId);
            string userId = GetNewIdNumber(IdNumberType.User);
            user.CompanyNo = CompanyNo;
            user.UserId = userId + GetUserIdRand();
            try
            {
                user.Permissions = Context.Configuration.First(m=>m.SettingName =="DefaultPermission").SettingValue;
                Context.User.AddObject(user);
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }
            catch (Exception ex)
            {
                PutbackNo(userId, IdNumberType.User);
                throw ex;
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0402", IsJson = true)]
        public JsonResult DeleteUser(string UserId)
        {
            JsonResult result = new JsonResult();

            User u = Context.User.FirstOrDefault(m => m.UserId == UserId && m.CompanyNo == CompanyNo);
            if (u == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else if (IS_DEMO)
            {
                result.Data = new { code = 1, message = MSG_IsDemo };
            }
            else
            {
                string sql = "Delete FROM  [UserDepartment] where UserId = @ID";
                var args = new DbParameter[] { 
                    new SqlParameter { ParameterName = "ID", Value = UserId} };
                Context.ExecuteStoreCommand(sql, args);

                Context.User.DeleteObject(u);

                Context.SaveChanges();

                result.Data = new { code = 0 };
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0402", IsJson = true)]
        public JsonResult ResetPassword(string UserId)
        {
            JsonResult result = new JsonResult();

            User u = Context.User.FirstOrDefault(m => m.UserId == UserId && m.CompanyNo == CompanyNo);
            if (u == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else if (IS_DEMO)
            {
                result.Data = new { code = 1, message = MSG_IsDemo };
            }
            else
            {
                string newPassword = MD5Utility.GetRandomPassword(6);
                string encryptedPassword = MD5Utility.MD5Encrypt(newPassword);
                u.Password = encryptedPassword;
                Context.SaveChanges();
                result.Data = new { code = 0, message = "密码重置成功!<br/>新密码：<span style='color:red;'>" + newPassword + "</span>" };

            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0402", IsJson = true)]
        public JsonResult UpdateUser(User user)
        {
            JsonResult result = new JsonResult();

            User u = Context.User.FirstOrDefault(m => m.UserId == user.UserId);
            if (u == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                u.UserName = user.UserName;
                u.Phone = user.Phone;
                u.Email = user.Email;
                u.Mobile = user.Mobile;
                u.Memo = user.Memo;

                Context.SaveChanges();
                result.Data = new { code = 0 };
            }

            return result;
        }

        public ActionResult Department()
        {
            List<Department> departments = Context.Department.Where(m => m.CompanyNo == CompanyNo).ToList();
            return View(departments);
        }

        public JsonResult GetDepartment(string DepartmentNo)
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            Department department = Context.Department.FirstOrDefault(m => m.DepartmentNo == DepartmentNo && m.CompanyNo == CompanyNo);

            if (department == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                result.Data = new { code = 0, data = new { DepartmentNo = department.DepartmentNo, DepartmentName = department.DepartmentName, DepartmentDescription = department.DepartmentDescription, Participate = department.Participate } };
            }

            return result;
        }

        public JsonResult AddDepartment(Department department)
        {
            JsonResult result = new JsonResult();

            string newNo = GetNewIdNumber(IdNumberType.Department);
            department.DepartmentNo = newNo;
            department.CompanyNo = CompanyNo;
            try
            {
                Context.Department.AddObject(department);
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }
            catch (Exception ex)
            {
                PutbackNo(newNo, IdNumberType.Department);
                throw ex;
            }


            return result;
        }

        public JsonResult DeleteDepartment(string DepartmentNo)
        {
            JsonResult result = new JsonResult();

            Department d = Context.Department.FirstOrDefault(m => m.DepartmentNo == DepartmentNo && m.CompanyNo == CompanyNo);
            if (d == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                Context.Department.DeleteObject(d);
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0402",IsJson=true)]
        public JsonResult UpdateUserDepartment(string UserId, string Department)
        {
            JsonResult result = new JsonResult();

            User u = Context.User.FirstOrDefault(m => m.UserId == UserId);
            if (u == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                string sql = "Delete FROM  [UserDepartment] where UserId = @ID";
                var args = new DbParameter[] { 
                    new SqlParameter { ParameterName = "ID", Value = UserId} };
                Context.ExecuteStoreCommand(sql, args);

                List<string> Departments = new JavaScriptSerializer().Deserialize(Department, typeof(List<string>)) as List<string>;
                foreach (string d in Departments)
                {
                    UserDepartment ud = new UserDepartment();
                    ud.UserId = UserId;
                    ud.DepartmentNo = d;
                    Context.UserDepartment.AddObject(ud);
                }
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0402",IsJson= true)]
        public JsonResult UpdateUserPermission(string UserId, string Permission)
        {
            JsonResult result = new JsonResult();

            User u = Context.User.FirstOrDefault(m => m.UserId == UserId);
            if (u == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else if (IS_DEMO)
            {
                result.Data = new { code = 1, message = MSG_IsDemo };
            }
            else
            {
                List<string> Permissions = new JavaScriptSerializer().Deserialize(Permission, typeof(List<string>)) as List<string>;

                u.Permissions = CombineIds(Permissions);
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }

            return result;
        }

        public JsonResult UpdateDepartment(Department department)
        {
            JsonResult result = new JsonResult();

            Department d = Context.Department.FirstOrDefault(m => m.DepartmentNo == department.DepartmentNo);
            if (d == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                d.DepartmentName = department.DepartmentName;
                d.DepartmentDescription = department.DepartmentDescription;
                d.Participate = department.Participate;

                Context.SaveChanges();
                result.Data = new { code = 0 };

            }

            return result;
        }

        #region Work Flow
        [PermissionAttribute(PermissionNo = "P0404")]
        public ActionResult WorkFlow()
        {
            List<WorkFlow> departments = Context.WorkFlow.Where(m => m.CompanyNo == CompanyNo).ToList();
            return View(departments);
        }

        public JsonResult GetWorkFlow(string WorkFlowNo)
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            WorkFlow department = Context.WorkFlow.FirstOrDefault(m => m.WorkFlowNo == WorkFlowNo && m.CompanyNo == CompanyNo);
            if (department == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                result.Data = new { code = 0, data = new { WorkFlowNo = department.WorkFlowNo, WorkFlowName = department.WorkFlowName, WorkFlowDescription = department.WorkFlowDescription } };
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0404",IsJson= true)]
        public JsonResult AddWorkFlow(WorkFlow workflow)
        {
            JsonResult result = new JsonResult();

            List<IdNumber> newNos = new List<IdNumber>();
            string newNo = GetNewIdNumber(IdNumberType.WorkFlow);
            string newStepNo1 = GetNewIdNumber(IdNumberType.WorkFlowStep);
            string newStepNo2 = GetNewIdNumber(IdNumberType.WorkFlowStep);
            newNos.Add(new IdNumber() { Type = IdNumberType.WorkFlow, No = newNo });
            newNos.Add(new IdNumber() { Type = IdNumberType.WorkFlowStep, No = newStepNo1 });
            newNos.Add(new IdNumber() { Type = IdNumberType.WorkFlowStep, No = newStepNo2 });
            workflow.WorkFlowNo = newNo;
            workflow.CompanyNo = CompanyNo;

            try
            {
                WorkFlowStep ws1 = new WorkFlowStep();
                ws1.WorkFlowStepNo = newStepNo1;
                ws1.WorkFlowStepName = "创建";
                ws1.WorkFlowNo = newNo;
                ws1.IsBeginPoint = true;
                ws1.IsEndPoint = false;
                ws1.IsSystemReserved = true;
                ws1.FollowupSteps = newStepNo2;
                ws1.StatusNo = CompanyNo + ORDER_STATUS_CREATED;
                ws1.SN = "01";
                ws1.CompanyNo = CompanyNo;

                WorkFlowStep ws2 = new WorkFlowStep();
                ws2.WorkFlowStepNo = newStepNo2;
                ws2.WorkFlowNo = newNo;
                ws2.WorkFlowStepName = "完成";
                ws2.IsBeginPoint = false;
                ws2.IsEndPoint = true;
                ws2.IsSystemReserved = true;
                ws2.StatusNo = CompanyNo + ORDER_STATIS_COMPLETE;
                ws2.SN = "99";
                ws2.CompanyNo = CompanyNo;

                Context.WorkFlow.AddObject(workflow);
                Context.WorkFlowStep.AddObject(ws1);
                Context.WorkFlowStep.AddObject(ws2);

                Context.SaveChanges();
                result.Data = new { code = 0 };
            }
            catch (Exception ex)
            {               
                PutbackNos(newNos);
                throw ex;
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0404", IsJson = true)]
        public JsonResult DeleteWorkFlow(string WorkFlowNo)
        {
            JsonResult result = new JsonResult();

            WorkFlow d = Context.WorkFlow.FirstOrDefault(m => m.WorkFlowNo == WorkFlowNo && m.CompanyNo == CompanyNo);
            if (d == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else if (IS_DEMO)
            {
                result.Data = new { code = 1, message = MSG_IsDemo };
            }
            else
            {
                string sql = "Delete FROM  [WorkFlowStep] where WorkFlowNo = @ID";
                var args = new DbParameter[] { 
                    new SqlParameter { ParameterName = "ID", Value = WorkFlowNo} };
                Context.ExecuteStoreCommand(sql, args);

                Context.WorkFlow.DeleteObject(d);
                Context.SaveChanges();
                result.Data = new { code = 0 };

            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0404", IsJson = true)]
        public JsonResult UpdateWorkFlow(WorkFlow workflow)
        {
            JsonResult result = new JsonResult();

            WorkFlow d = Context.WorkFlow.FirstOrDefault(m => m.WorkFlowNo == workflow.WorkFlowNo);
            if (d == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                d.WorkFlowName = workflow.WorkFlowName;
                d.WorkFlowDescription = workflow.WorkFlowDescription;

                Context.SaveChanges();
                result.Data = new { code = 0 };
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0404", IsJson = true)]
        public JsonResult AddWorkFlowStep(string Users, string FollowUps, string WorkFlowNo, string StatusNo, string WorkFlowStepName, string SN)
        {
            // TBD
            // By now, we only support maximum 10 steps.
            JsonResult result = new JsonResult();

            WorkFlow d = Context.WorkFlow.FirstOrDefault(m => m.WorkFlowNo == WorkFlowNo);
            if (d == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                WorkFlowStep newStep = new WorkFlowStep();
                string newStepNo = GetNewIdNumber(IdNumberType.WorkFlowStep);
                try
                {
                    newStep.WorkFlowStepNo = newStepNo;
                    newStep.WorkFlowStepName = WorkFlowStepName;

                    JavaScriptSerializer js = new JavaScriptSerializer();

                    List<string> temp;
                    if (!string.IsNullOrEmpty(Users))
                    {
                        temp = js.Deserialize(Users, typeof(List<string>)) as List<String>;
                        newStep.UserIds = CombineIds(temp);
                    }

                    if (!string.IsNullOrEmpty(FollowUps))
                    {
                        temp = js.Deserialize(FollowUps, typeof(List<string>)) as List<String>;
                        newStep.FollowupSteps = CombineIds(temp);
                    }

                    newStep.StatusNo = StatusNo;
                    newStep.WorkFlowNo = WorkFlowNo;
                    newStep.SN = SN;
                    newStep.IsBeginPoint = false;
                    newStep.IsEndPoint = false;
                    newStep.IsSystemReserved = false;
                    newStep.CompanyNo = CompanyNo;
                    Context.WorkFlowStep.AddObject(newStep);
                    Context.SaveChanges();
                    result.Data = new { code = 0 };
                }
                catch (Exception ex)
                {
                    PutbackNo(newStepNo, IdNumberType.WorkFlowStep);
                    throw ex;
                }
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0404", IsJson = true)]
        public JsonResult UpdateWorkFlowStep(string Users, string FollowUps, string WorkFlowNo, string WorkFlowStepNo, string StatusNo, string WorkFlowStepName, string SN)
        {
            JsonResult result = new JsonResult();

            WorkFlow d = Context.WorkFlow.FirstOrDefault(m => m.WorkFlowNo == WorkFlowNo);
            if (d == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else if (IS_DEMO)
            {
                result.Data = new { code = 1, message = MSG_IsDemo };
            }
            else
            {
                WorkFlowStep step = Context.WorkFlowStep.FirstOrDefault(m => m.WorkFlowStepNo == WorkFlowStepNo);
                if (step == null)
                {
                    result.Data = new { code = 1, message = MSG_NoEntityFound };
                }
                else
                {
                    step.WorkFlowStepName = WorkFlowStepName;

                    JavaScriptSerializer js = new JavaScriptSerializer();

                    List<string> temp;
                    if (!string.IsNullOrEmpty(Users))
                    {
                        temp = js.Deserialize(Users, typeof(List<string>)) as List<String>;
                        step.UserIds = CombineIds(temp);
                    }

                    if (!string.IsNullOrEmpty(FollowUps))
                    {
                        temp = js.Deserialize(FollowUps, typeof(List<string>)) as List<String>;
                        step.FollowupSteps = CombineIds(temp);
                    }

                    step.StatusNo = StatusNo;
                    step.SN = SN;

                    Context.SaveChanges();
                    result.Data = new { code = 0 };

                }

            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0404", IsJson = true)]
        public JsonResult DeleteWorkFlowStep(string WorkFlowStepNo)
        {
            JsonResult result = new JsonResult();

            WorkFlowStep d = Context.WorkFlowStep.FirstOrDefault(m => m.WorkFlowStepNo == WorkFlowStepNo);
            if (d == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else if (IS_DEMO)
            {
                result.Data = new { code = 1, message = MSG_IsDemo };
            }
            else
            {
                Context.WorkFlowStep.DeleteObject(d);
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0404")]
        public ActionResult WorkFlowDetail(string WorkFlowNo)
        {

            WorkFlow wf = Context.WorkFlow.FirstOrDefault(m => m.WorkFlowNo == WorkFlowNo && m.CompanyNo == CompanyNo);
            if (wf == null)
            {
                throw new NoEntityFound();
            }
            else
            {
                WorkFlowDetailModel model = GetWorkFlowDetailMode(WorkFlowNo);
                model.WorkFlowName = wf.WorkFlowName;
                model.DdlOrderStatus = BindOrderStatusDdl();
                model.WorkFlowNo = wf.WorkFlowNo;
                return View(model);
            }
        }

        public WorkFlowDetailModel GetWorkFlowDetailMode(string WorkFlowNo)
        {
            WorkFlowDetailModel model = new WorkFlowDetailModel();
            model.DdlOrderStatus = BindOrderStatusDdl();
            WorkFlow wf = Context.WorkFlow.FirstOrDefault(m => m.WorkFlowNo == WorkFlowNo && m.CompanyNo == CompanyNo);
            if (wf == null)
            {
                return null;
            }
            else
            {
                List<WorkFlowStep> steps = Context.WorkFlowStep.Where(m => m.WorkFlowNo == WorkFlowNo).OrderBy(m => m.SN).ToList();

                List<WorkFlowStepModel> jsSteps = new List<WorkFlowStepModel>();
                foreach (WorkFlowStep s in steps)
                {
                    WorkFlowStepModel wsm = new WorkFlowStepModel();
                    wsm.WorkFlowStepNo = s.WorkFlowStepNo;
                    wsm.WorkFlowStepName = s.WorkFlowStepName;
                    wsm.WorkFlowNo = s.WorkFlowNo;
                    wsm.CanMarkComplete = s.CanMarkComplete;
                    wsm.StatusNo = s.StatusNo;
                    wsm.StatusName = s.OrderStatus.StatusName;
                    wsm.FollowUps = new List<ListOption>();
                    wsm.Users = new List<ListOption>();
                    wsm.SN = s.SN;
                    wsm.IsSystemReserved = s.IsSystemReserved;

                    List<string> temp;
                    if (!string.IsNullOrEmpty(s.UserIds))
                    {
                        temp = s.UserIds.Split(',').ToList();

                        foreach (string t in temp)
                        {
                            User u = Context.User.FirstOrDefault(m => m.UserId == t);
                            if (u != null)
                            {
                                wsm.Users.Add(new ListOption() { OptionText = u.UserName, OptionValue = u.UserId });
                            }
                        }
                    }


                    if (!string.IsNullOrEmpty(s.FollowupSteps))
                    {
                        temp = s.FollowupSteps.Split(',').ToList();

                        foreach (string t in temp)
                        {
                            WorkFlowStep ws = Context.WorkFlowStep.FirstOrDefault(m => m.WorkFlowStepNo == t);
                            if (ws != null)
                            {
                                wsm.FollowUps.Add(new ListOption() { OptionText = ws.WorkFlowStepName, OptionValue = ws.WorkFlowStepNo });
                            }
                        }
                    }

                    wsm.WorkFlowStepNo = s.WorkFlowStepNo;

                    jsSteps.Add(wsm);
                }

                model.Steps = jsSteps;

                return model;
            }
        }

        [PermissionAttribute(PermissionNo = "P0404", IsJson = true)]
        public JsonResult GetWorkFlowStep(string WorkFlowNo, string WorkFlowStepNo)
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            WorkFlow wf = Context.WorkFlow.FirstOrDefault(m => m.WorkFlowNo == WorkFlowNo && m.CompanyNo == CompanyNo);
            if (wf == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                WorkFlowStepModel model = new WorkFlowStepModel();
                model.Users = Context.User.Where(m => m.CompanyNo == CompanyNo).Select(m => new ListOption { OptionText = m.UserName, OptionValue = m.UserId, AdditionalValue = "0" }).ToList();
                model.FollowUps = Context.WorkFlowStep.Where(m => m.WorkFlowNo == WorkFlowNo).Select(m => new ListOption { OptionText = m.WorkFlowStepName, AdditionalValue = "0", OptionValue = m.WorkFlowStepNo }).ToList();

                if (string.IsNullOrEmpty(WorkFlowStepNo))   // New
                {
                }
                else // Edit                
                {
                    WorkFlowStep step = Context.WorkFlowStep.FirstOrDefault(m => m.WorkFlowStepNo == WorkFlowStepNo);
                    if (step == null)
                    {
                        result.Data = new { code = 1, message = "流程步骤不存在" };
                    }
                    else
                    {
                        model.WorkFlowStepNo = step.WorkFlowStepNo;
                        model.WorkFlowStepName = step.WorkFlowStepName;
                        model.StatusNo = step.StatusNo;
                        model.SN = step.SN;
                        model.IsSystemReserved = step.IsSystemReserved;
                        model.IsBeginPoint = step.IsBeginPoint;
                        model.IsEndPoint = step.IsEndPoint;

                        List<string> temp;
                        if (!string.IsNullOrEmpty(step.UserIds))
                        {
                            temp = step.UserIds.Split(',').ToList();
                            foreach (string t in temp)
                            {
                                ListOption lo = model.Users.FirstOrDefault(m => m.OptionValue == t);
                                if (lo != null)
                                {
                                    lo.AdditionalValue = "1";
                                }
                            }
                        }
                        if (!string.IsNullOrEmpty(step.FollowupSteps))
                        {
                            temp = step.FollowupSteps.Split(',').ToList();
                            foreach (string t in temp)
                            {
                                ListOption lo = model.FollowUps.FirstOrDefault(m => m.OptionValue == t);
                                if (lo != null)
                                {
                                    lo.AdditionalValue = "1";
                                }
                            }
                        }
                    }
                }

                result.Data = new { code = 0, data = model };

            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0404", IsJson = true)]
        public JsonResult GetWorkFlowDetail(string WorkFlowNo)
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            WorkFlow wf = Context.WorkFlow.FirstOrDefault(m => m.WorkFlowNo == WorkFlowNo && m.CompanyNo == CompanyNo);
            if (wf == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                WorkFlowDetailModel model = GetWorkFlowDetailMode(WorkFlowNo);
                model.WorkFlowName = wf.WorkFlowName;
                result.Data = new { code = 0, data = model };
            }

            return result;
        }
        #endregion

        [PermissionAttribute(PermissionNo = "P0405")]
        public ActionResult List()
        {
            ListModel list = new ListModel();
            list.OrderStatus = Context.OrderStatus.Where(m => m.CompanyNo == CompanyNo).ToList();
            list.PaymentTypes = Context.PaymentType.Where(m => m.CompanyNo == CompanyNo).ToList();
            list.ContributionRatio = Context.ContributionRatio.Where(m => m.CompanyNo == CompanyNo).OrderBy(m => m.RatioNumber).ToList();

            return View(list);
        }

        #region Payment Type

        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult AddPaymentType(PaymentType paymentType)
        {
            JsonResult result = new JsonResult();

            string newPaymentNo = GetNewIdNumber(IdNumberType.PaymentType);
            paymentType.PaymentTypeNo = newPaymentNo;

            paymentType.CompanyNo = CompanyNo;

            try
            {
                Context.PaymentType.AddObject(paymentType);
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }
            catch (Exception ex)
            {
                PutbackNo(newPaymentNo, IdNumberType.PaymentType);
                throw ex;
            }

            return result;
        }

        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult UpdatePaymentType(PaymentType paymentType)
        {
            JsonResult result = new JsonResult();

            PaymentType pt = Context.PaymentType.FirstOrDefault(m => m.PaymentTypeNo == paymentType.PaymentTypeNo && m.CompanyNo == CompanyNo);

            if (pt == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                pt.TypeName = paymentType.TypeName;
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }

            return result;
        }

        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult DeletePaymentType(string PaymentTypeNo)
        {
            JsonResult result = new JsonResult();
            string errorMessage = string.Empty;
            PaymentType originalPaymentType = Context.PaymentType.FirstOrDefault(m => m.PaymentTypeNo == PaymentTypeNo && m.CompanyNo == CompanyNo);

            if (originalPaymentType == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else if (IS_DEMO)
            {
                result.Data = new { code = 1, message = MSG_IsDemo };
            }
            else
            {
                Context.PaymentType.DeleteObject(originalPaymentType);
                Context.SaveChanges();
                result.Data = new { code = 0 };

            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult GetPaymentType(string PaymentTypeNo)
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            PaymentType paymentType = Context.PaymentType.FirstOrDefault(m => m.PaymentTypeNo == PaymentTypeNo);
            if (paymentType == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                result.Data = new { code = 0, data = new { PaymentTypeNo = paymentType.PaymentTypeNo, TypeName = paymentType.TypeName, CompanyNo = paymentType.CompanyNo } };
            }

            return result;
        }
        #endregion

        #region Order Status
        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult AddOrderStatus(OrderStatus orderStatus)
        {
            JsonResult result = new JsonResult();

            string newOrderStatus = GetNewIdNumber(IdNumberType.OrderStatus);
            orderStatus.StatusNo = newOrderStatus;

            orderStatus.CompanyNo = CompanyNo;
            try
            {
                Context.OrderStatus.AddObject(orderStatus);
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }
            catch (Exception ex)
            {
                PutbackNo(newOrderStatus, IdNumberType.OrderStatus);
                throw ex;
            }

            return result;
        }

        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult UpdateOrderStatus(OrderStatus orderStatus)
        {
            JsonResult result = new JsonResult();

            OrderStatus os = Context.OrderStatus.FirstOrDefault(m => m.StatusNo == orderStatus.StatusNo && m.CompanyNo == CompanyNo);

            if (os == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                os.StatusName = orderStatus.StatusName;
                Context.SaveChanges();
                result.Data = new { code = 0 };

            }

            return result;
        }

        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult DeleteOrderStatus(string StatusNo)
        {
            JsonResult result = new JsonResult();
            string errorMessage = string.Empty;
            OrderStatus originalOrderStatus = Context.OrderStatus.FirstOrDefault(m => m.StatusNo == StatusNo && m.CompanyNo == CompanyNo);

            if (originalOrderStatus == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else if (IS_DEMO)
            {
                result.Data = new { code = 1, message = MSG_IsDemo };
            }
            else
            {
                Context.OrderStatus.DeleteObject(originalOrderStatus);
                Context.SaveChanges();
                result.Data = new { code = 0 };

            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult GetOrderStatus(string StatusNo)
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            OrderStatus orderStatus = Context.OrderStatus.FirstOrDefault(m => m.StatusNo == StatusNo && m.IsSystemReversed == false);
            if (orderStatus == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                result.Data = new { code = 0, data = new { StatusNo = orderStatus.StatusNo, StatusName = orderStatus.StatusName, CompanyNo = orderStatus.CompanyNo } };
            }

            return result;
        }
        #endregion

        #region Contribution Ratio
        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult AddContributionRatio(ContributionRatio contributionRatio)
        {
            JsonResult result = new JsonResult();

            string newContributionRatioNo = GetNewIdNumber(IdNumberType.ContributionRatio);
            contributionRatio.RatioNo = newContributionRatioNo;

            contributionRatio.CompanyNo = CompanyNo;
            try
            {
                Context.ContributionRatio.AddObject(contributionRatio);
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }
            catch (Exception ex)
            {
                PutbackNo(newContributionRatioNo, IdNumberType.ContributionRatio);
                throw ex;
            }

            return result;
        }

        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult UpdateContributionRatio(ContributionRatio contributionRatio)
        {
            JsonResult result = new JsonResult();

            ContributionRatio os = Context.ContributionRatio.FirstOrDefault(m => m.RatioNo == contributionRatio.RatioNo && m.CompanyNo == CompanyNo);

            if (os == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                os.RatioNumber = contributionRatio.RatioNumber;
                Context.SaveChanges();
                result.Data = new { code = 0 };

            }

            return result;
        }

        [HttpPost]
        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult DeleteContributionRatio(string RatioNo)
        {
            JsonResult result = new JsonResult();
            string errorMessage = string.Empty;
            ContributionRatio originalContributionRatio = Context.ContributionRatio.FirstOrDefault(m => m.RatioNo == RatioNo && m.CompanyNo == CompanyNo);

            if (originalContributionRatio == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                Context.ContributionRatio.DeleteObject(originalContributionRatio);
                Context.SaveChanges();
                result.Data = new { code = 0 };
            }

            return result;
        }

        [PermissionAttribute(PermissionNo = "P0405", IsJson = true)]
        public JsonResult GetContributionRatio(string RatioNo)
        {
            JsonResult result = new JsonResult();
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            ContributionRatio contributionRatio = Context.ContributionRatio.FirstOrDefault(m => m.RatioNo == RatioNo);
            if (contributionRatio == null)
            {
                result.Data = new { code = 1, message = MSG_NoEntityFound };
            }
            else
            {
                result.Data = new { code = 0, data = new { RatioNo = contributionRatio.RatioNo, RatioNumber = contributionRatio.RatioNumber, CompanyNo = contributionRatio.CompanyNo } };
            }

            return result;
        }
        #endregion

        public string GetUserIdRand()
        {
            Random r = new Random();
            return r.Next(1, 9).ToString();
        }
    }
}
